home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 46
/
Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso
/
-in_the_mag-
/
banging_the_metal
/
draw_logic
/
draw_asm
next >
Wrap
Text File
|
1996-08-20
|
8KB
|
188 lines
* QL WORLD DIY TOOLKIT - FAST pixel graphics routines
* Version 1.6, Copyright 1989,90 Simon N Goodwin.
* Modified 10/9/89 to support Thor XVI MODE 12.
* Modified 19/7/90 to suit Metacomco's Assembler.
*
xstore equ 84 Offsets of old X & Y
ystore equ 78 in the channel block
*
start lea.l define,a1
move.w $110,a2 BP.INIT vector
jmp (a2)
*
draw lea.l drawer,a4
bra.s get_params
plot lea.l plotter,a4
*
* Handler for 2 or 3 parameters
*
get_params move.w $112,a2 Vector to get integers
jsr (a2) CA.GTINT
bne.s bad_exit
moveq #1,d0 First assume channel 1
subq.w #2,d3 At least 2 parameters?
beq.s get_coords Exactly 2, use #1
bmi.s bad_param Less than 2: an error
subq.w #1,d3 Only 1 parameter left?
bne.s bad_param No, too many, complain
move.w 0(a1,a6.l),d0 Get BASIC channel No.
addq.l #2,a1 Discard channel param.
get_coords move.w 0(a1,a6.l),d1 Get X co-ordinate
move.w 2(a1,a6.l),d2 Get Y co-ordinate
*
* Convert channel number in D0 to ID in A0 and call EXTOP
*
chan_sel mulu #40,d0 Channel table size
add.l $30(a6),d0 Add base offset
cmp.l $34(a6),d0
bge.s what_chan Past end of table?
move.l 0(a6,d0.l),d0
bmi.s what_chan Negative if closed
call_extop move.l d0,a0 A0 is channel ID
move.l a4,a2 Address of routine
moveq #-1,d3 Allow infinite time
moveq #9,d0 SD.EXTOP key
trap #3 Call the device driver
rts Return D0 from EXTOP
*
bad_param moveq #-15,d0 BAD PARAMETER error
rts
what_chan moveq #-6,d0 CHANNEL NOT OPEN error
bad_exit rts Error code is in D0
*
* Line DRAW routine
*
drawer move.w xstore(a0),d4 Fetch previous X
move.w ystore(a0),d5 Fetch previous Y
bsr range_chk Line must fit window
find_DX suba.l a2,a2 DX := 0
sub.w d4,d1
beq.s set_X_step
bmi.s neg_DX
addq.l #1,a2 A2 := SIGN( Delta X )
bra.s set_X_step
neg_DX subq.l #1,a2
neg.w d1 D1 := ABS( Delta X )
set_X_step btst #3,52(a6) Check mode (SV.MCSTA)
beq.s find_DY MODE 4, D1 & A2 are OK
adda.l a2,a2 MODE 8/12, double X step
ror.w #1,d1 And halve X dot count
find_DY suba.l a3,a3 DY := 0
sub.w d5,d2
beq.s find_DD
bmi.s neg_DY
addq.l #1,a3 A3 := SIGN( Delta Y )
bra.s find_DD
neg_DY subq.l #1,a3
neg.w d2 D2 := ABS( Delta Y )
find_DD cmp.w d1,d2 D1 := MAX( D1, D2 )
bhi.s y_bigger
no_match move.w a2,a4 DDX := DX
suba.l a5,a5 DDY := 0
bra.s find_TEMP
y_bigger exg d1,d2 D1 := MAX( D1,D2 )
suba.l a4,a4 DDX := 0
move.w a3,a5 DDY := DY
find_TEMP move.w d1,d0
asr.w #1,d0 TEMP := STEPS DIV 2
move.w d2,d6 D6 := PARTS
move.w d1,d2
subq.w #1,d2 D2 is DOT for DBRA
bmi.s null_draw Exit if line length=0
exg d1,d4 OLDX = D1; STEPS = D4
exg d2,d5 OLDY = D2; DOT = D5
*
* Now draw a line of D5 pixels; D1,D2 = X,Y of next point
*
dot_loop add.w d6,d0 TEMP := TEMP + PARTS
cmp.w d4,d0 Flag TEMP - STEPS
bcs.s use_DD
sub.w d4,d0 TEMP := TEMP - STEPS
add.w a2,d1 OLDX := OLDX + DX
add.w a3,d2 OLDY := OLDY + DY
bra.s do_dot
*
use_DD add.w a4,d1 OLDX := OLDX + DDX
add.w a5,d2 OLDY := OLDY + DDY
do_dot movem.w d1-d2,-(a7) Preserve OLDX & OLDY
bsr.s plot_pixel
movem.w (a7)+,d1-d2 Restore OLDX & OLDY
dbra d5,dot_loop
null_draw moveq #0,d0
rts
*
* Co-ordinate checker; D1=X, D2=Y, ERR.OR if beyond window
*
range_chk tst.b 51(a6) Test SV.SCRST
bne.s screen_off Abort if CTRL-F5 set
tst.w d2 Check Y >= 0
bmi.s range_err
cmp.w 30(a0),d2 Check Y < CH.HEIGHT
bcc.s range_err
tst.w d1 Check X >= 0
bmi.s range_err
cmp.w 28(a0),d1 Check X < CH.WIDTH
bcc.s range_err
move.w #$8080,d7 Set MODE 4 pixel mask
btst #3,52(a6) Check MODE (SV.MCSTA)
beq.s range_ok MODE 4, no problems
bclr #0,d1 MODE 8/12, X must be EVEN
btst #2,52(a6) Test Thor MODE 12 bit
beq.s not_a_thor
move.w #$C0C0,d7 Use the Thor mask
not_a_thor move.b #$C0,d7 Mask 8 colours
range_ok add.w 24(a0),d1 Add window offset to X
add.w 26(a0),d2 Add window offset to Y
move.w d1,xstore(a0) Store end X on SD.XORG
move.w d2,ystore(a0) Store end Y on SD.YORG
rts
*
screen_off moveq #-1,d0 NOT COMPLETE error
bra.s quick_exit
range_err moveq #-4,d0 OUT OF RANGE error
quick_exit addq.l #4,a7 Return to after TRAP
rts
*
* Pixel PLOT code, uses A0, A6, D7; alters A1, D1, D2, D3
*
plotter bsr.s range_chk
moveq #0,d0 Preset ERR.OK report
plot_pixel move.l 62(a0),d3 Grab the ink mask
btst #0,d2 Find out if Y is odd
beq.s find_word It's even, mask is OK
swap d3 Odd, so use other mask
*
* Point A1 at the relevant word in video memory
*
find_word move.l 50(a0),a1 A1 := screen RAM start
lsl.w #7,d2 1 line= 2^7= 128 bytes
adda.w d2,a1 A1 := line RAM start
moveq #7,d2
and.w d1,d2 Save X MOD 8 in D2
lsr.w #3,d1 D1 := offset on line
add.w d1,d1 Offset := 0-126 (EVEN)
adda.w d1,a1 A1 -> screen RAM word
*
* Set the pixel in MODE 4 or 8, allowing for OVER -1
*
set_pixel move.w d7,d1 Select pixel mask
ror.w d2,d1 Align pixel mask
and.w d1,d3 D3 := 1 pixel of ink
btst #3,66(a0) Check for OVER -1
bne.s overplot
not.w d1 Mask out the rest
and.w (a1),d1 Fetch the background
or.w d3,d1 Insert the pixel
move.w d1,(a1) Store the combination
rts PLOT returns ERR.OK
overplot eor.w d3,(a1) Exclusive OR the pixel
rts
*
define dc.w 2 Number of procs
dc.w plot-*
dc.b 4,'PLOT'
dc.w draw-*
dc.b 4,'DRAW'
dc.w 0,0,0 End of procs, no fns
end